# Table_A09a-A14a.R

# Part of the replication archive for 
#
#   Bullock, John G. 2020. "Education and Attitudes toward Redistribution in
#   the United States." British Journal of Political Science 50.


# This file produces Tables A9a through A14a in the appendix to the article. 
# The tables report first-stage estimates.


library(Bullock, lib.loc = c(.libPaths(), 'packageLibrary'))            # for qw()
library(stringr)            # for str_pad()
source('IV_setup.R')
source('functions/getClusters.R')



##############################################################################
# CREATE ENVIRONMENTS WITH THE FIRST-STAGE MODELS
##############################################################################
IVModelsEnvFirstStage <- eapply(IVModelsEnv, getFirstStage, endog = 'educ')
IVModelsEnvFirstStage <- addModNumAttribute(IVModelsEnvFirstStage)
IVModelsEnvFirstStage <- list2env(IVModelsEnvFirstStage)

IVModelsEnvFirstStage.r <- eapply(
  IVModelsEnvFirstStage, 
  function (x) update(x, . ~ . - CA.fac))
IVModelsEnvFirstStage.r <- addModNumAttribute(IVModelsEnvFirstStage.r)
IVModelsEnvFirstStage.r <- list2env(IVModelsEnvFirstStage.r)



##############################################################################
# CREATE DATA FRAMES FOR ESTIMATION
##############################################################################
GSS.df$educ1      <- GSS.df$educ2 <- GSS.df$educ5 <- GSS.df$educ6 <- GSS.df$educ
ANES.df$educ3     <- ANES.df$educ4 <- ANES.df$educ


# The first-stage models should be estimated with the same datasets that are 
# used to estimate the second-stage models.
GSS.df.eqwlth     <- GSS.df [!is.na(GSS.df$eqwlth), ]
GSS.df.goveqinc   <- GSS.df [!is.na(GSS.df$goveqinc), ]
ANES.df.guarantee <- ANES.df[!is.na(ANES.df$guarantee.7pt), ]
ANES.df.health    <- ANES.df[!is.na(ANES.df$govt.health.7pt), ]
GSS.df.helppoor   <- GSS.df [!is.na(GSS.df$helppoor), ]
GSS.df.welfare    <- GSS.df [!is.na(GSS.df$welfare), ]



##############################################################################
# ESTIMATE MODELS
##############################################################################
dfNames  <- qw(
  "GSS.df.eqwlth  GSS.df.goveqinc ANES.df.guarantee
   ANES.df.health GSS.df.helppoor GSS.df.welfare") 
varNamesEduc <- paste0('educ',   1:length(dfNames))
FirstStageEducModelObjectsEnv <- estimateModels(
  varNames     = varNamesEduc, 
  modelEnvir   = IVModelsEnvFirstStage,  
  dfNames      = dfNames,
  estFun       = lm,
  objectSuffix = '.lm') 
FirstStageEducModelObjectsEnv.r <- estimateModels(
  varNames     = varNamesEduc, 
  modelEnvir   = IVModelsEnvFirstStage.r,  
  dfNames      = dfNames,
  estFun       = lm,
  objectSuffix = '.lm') 



##############################################################################
# GET F STATISTICS
##############################################################################
Fstats <- mapply(
  function (x, y) anova(x, y)$F[2], 
  as.list(FirstStageEducModelObjectsEnv)  [sort(names(FirstStageEducModelObjectsEnv))], 
  as.list(FirstStageEducModelObjectsEnv.r)[sort(names(FirstStageEducModelObjectsEnv.r))])



##############################################################################
# MAKE ASCII TABLES
##############################################################################
firstStageObjs      <- list()
firstStageClusters  <- list()
firstStageRegTables <- list()
secondStageResponse <- qw("eqwlth goveqinc guarantee.7pt govt.health.7pt helppoor welfare")
for (depvar in 1:length(secondStageResponse)) {
  firstStageObjs[[secondStageResponse[depvar]]] <-  
    mget(
      ls(pat = paste0('educ', depvar), envir = FirstStageEducModelObjectsEnv),
      envir = FirstStageEducModelObjectsEnv)    
  firstStageClusters[[secondStageResponse[depvar]]] <- lapply(
    firstStageObjs[[secondStageResponse[depvar]]],
    getClusters)
  firstStageRegTables[[secondStageResponse[depvar]]] <- regTable(
      firstStageObjs[[secondStageResponse[depvar]]],
      rowsToKeep = list('CA.fac', 'CL.fac'),
      clusterSEs = TRUE,
      clusterVar = firstStageClusters[[secondStageResponse[depvar]]])  
}



##############################################################################
# CONSTRUCT CAPTIONS FOR LATEX TABLES
##############################################################################
datasetNames        <- qw("GSS GSS ANES ANES GSS GSS") 
capString1          <- '\\textit{First stage: effects of compulsory schooling laws on educational attainment ('
FstatsNameSorted  <- Fstats  
secondStageResponseFullName <- c(
  'redistribution to poor 1, GSS', 
  'redistribution to poor 2, GSS',
  'guaranteed standard of living, ANES', 
  'health care, ANES', 
  'help the poor, GSS', 
  'welfare, GSS')
captionStrings <- paste0(
  capString1, 
  secondStageResponseFullName,  
  ').}  Cell entries are OLS estimates and standard errors.  The response variable is years of education. Standard errors are clustered at the state-year level.')   



##############################################################################
# MAKE LATEX TABLES
##############################################################################
firstStageLatexTables <- list()
modelRownames <- c(
  'CA $\\in$ \\{8, 9, 10\\}',
  'CA $\\geq$ 11'
)
modelColnames <- list(
  c('',          '',               '',             'with'),
  c('',          'with',           'with',         'political and'),
  c('',          'cohort-year',    'state-year',   'demographic'),
  c('baseline',  'fixed effects',  'trend vars.',  'controls'))  
for (depvar in 1:length(secondStageResponse)) {
  R2     <- sapply(firstStageObjs[[depvar]], function (x) summary(x)$r.squared )
  SER    <- sapply(firstStageObjs[[depvar]], function (x) summary(x)$sigma )
  SER    <- gsub('^0\\.', '.', round(SER, 2))
  Fstat  <- Fstats[grepl(paste0('educ', depvar), names(Fstats))]
  Fstat  <- as.character(round(Fstat, 2))
  Fstat  <- gsub('^(\\d?\\d)$', '\\1.00', Fstat)  # e.g., change "57"   to "57.00"
  Fstat  <- gsub('(\\.\\d)$', '\\10', Fstat)      # e.g., change "57.4" to "57.40"
  N      <- sapply(firstStageObjs[[depvar]], nobs)
  footerRows <- list(
    c('$R^2$', str_pad(round(R2, 2), 4, side = 'right', pad = '0')),
    c('Standard error of regression', SER),
    c('\\textit{F} for exclusion of instruments', Fstat),
    c('Number of observations', N))
  firstStageLatexTables[[secondStageResponse[depvar]]] <- latexTable(
    mat                = firstStageRegTables[[secondStageResponse[depvar]]], 
    rowNames           = modelRownames,
    colNames           = modelColnames,  
    colNameExpand      = FALSE,
    decimalPlaces      = 3,
    hspace             = '-.3125in',
    spacerColumns      = seq(0, ncol(firstStageRegTables[[secondStageResponse[depvar]]]) - 1, by = 2),  # after rowname and after each SE column  
    spacerColumnsWidth = '1.05em',  
    headerFooter       = TRUE,
    footerRows         = footerRows,
    caption            = captionStrings[depvar],
    captionMargins     = c('.3in', '.3in'),   
    commandName        = gsub(
      pattern     = '(\\.|\\dpt)', 
      replacement = '', 
      x           = paste0('TabFirstStage', secondStageResponse[depvar])),
    callCommand        = FALSE)  # FALSE unless producing a standalone PDF file
}

# TWEAK TABLE FORMATTING
tweakTables <- function (myTable) {
  myIndex <- grep('{{\\hspace*{0em}}}N', myTable, fixed = TRUE)
  myTable[myIndex[2]] <- sub(
    pattern     = '{{\\hspace*{0em}}}N{0}{3}',
    replacement = '{{\\hspace*{0em}}}N{1}{3}',
    x           = myTable[myIndex[2]],
    fixed       = TRUE)
  myTable[myIndex[4]] <- sub(
    pattern     = '{{\\hspace*{0em}}}N{0}{3}',
    replacement = '{{\\hspace*{.25em}}}N{1}{3}',
    x           = myTable[myIndex[4]],
    fixed       = TRUE)
  myTable
}
firstStageLatexTables <- lapply(firstStageLatexTables, tweakTables)



##############################################################################
# MAKE PDF FILE
##############################################################################
latexTablePDF(
  latexCommands      = firstStageLatexTables, 
  firstPageEmpty     = FALSE,
  continuedFloatStar = TRUE,                   # For first figure in a series, e.g., first-stage tables in appendix
  wrapper            = FALSE,                  # FALSE if inserting LaTeX tables into appendix of my paper
  outputFilenameStem = 'float_output/Table_A09a-A14a',       
  overwriteExisting  = TRUE,
  keepPDFFile        = FALSE,
  keepTexFile        = TRUE,
  openPDFOnExit      = FALSE)
